package net.cyndeline.rldungeon.dgs.strategy.pointlessArea.help

import net.cyndeline.rldungeon.dgs.graph.Room
import net.cyndeline.rldungeon.dgs.strategy.help.CollapsedNode
import com.escalatesoft.subcut.inject.{BindingModule, Injectable}
import scala.util.Random
import net.cyndeline.rldungeon.util.{RandomElementFinderInterface, RandomElementFinder}
import net.cyndeline.rldungeon.dgs.strategy.pointlessArea.RepresentedVertexFinder

/**
 * Selects a random represented vertex from a super node.
 */
class RandomRepresentedVertexFinder[V <: Room[V]](random: Random)(implicit val bindingModule: BindingModule)
  extends Injectable
  with RepresentedVertexFinder[V] {
  private val elementFinder = injectOptional[RandomElementFinderInterface] getOrElse { new RandomElementFinder() }

  /**
   * Finds any represented vertex.
   * @param node Super-node to select vertex from.
   * @return A vertex contained in the super-node. Guaranteed to exist since every node represents at least one vertex.
   */
  def findVertex(node: CollapsedNode[V]): V = elementFinder.findRandomElement(node.vertexCollection, random)

  /**
   * Finds a represented vertex that can hold at least one additional reward.
   * @param node Super-node to select vertex from.
   * @return A vertex that can hold an additional reward, or None if no such vertex exists.
   */
  def findVertexThatHoldsRewards(node: CollapsedNode[V]): Option[V] = {
    val rewardVertices = node.allVerticesThatCanHoldRewards

    if (!rewardVertices.isEmpty)
      Option(elementFinder.findRandomElement(rewardVertices, random))
    else
      None
  }

  /**
   * Finds a represented vertex that can hold at least one additional activator.
   * @param node Super-node to select vertex from.
   * @return A vertex that can hold an additional activator, or None if no such vertex exists.
   */
  def findVertexThatHoldsActivators(node: CollapsedNode[V]): Option[V] = {
    val activatorVertices = node.allVerticesThatCanHolActivators

    if (!activatorVertices.isEmpty)
      Option(elementFinder.findRandomElement(activatorVertices, random))
    else
      None
  }
}
